home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 123_01 / ar1.bds < prev    next >
Text File  |  1985-03-09  |  14KB  |  790 lines

  1. /*
  2.     archive - BDS C version
  3.  
  4.     translated from Software Tools ar/ver1.rat by:
  5.  
  6.         Oscar Goldman
  7.         1221 Knox Road
  8.         Wynnewood, PA 19096
  9.  
  10.     converted to use BDS C library by:
  11.  
  12.         Edward K. Ream
  13.         1850 Summit Ave.
  14.         Madison, WI 53705
  15.         (608) 231 -2952
  16.  
  17.     version: May 5, 1982; February 24, 1983
  18. */
  19.  
  20. #include "bdscio.h"
  21. #include "dio.h"
  22. #include "date.h"
  23.  
  24.  
  25. #define MAXLINE 300        /*  maximum line size */
  26. #define MAXCHARS 30
  27. #define NEWLINE '\n'
  28. #define EOS 0
  29. #define YES 1
  30. #define NO 0
  31.  
  32. #define    MAXFILES  100        /*  maximum number of files processable */
  33. #define SYS_MAXFN 15
  34.  
  35. #define    DELETE_CMD    'd'    /*  delete member from archive */
  36. #define    PRINT_CMD    'p'    /*  print archive members */
  37. #define    TABLE_CMD    't'    /*  print table of contents */
  38. #define    UPDATE_CMD    'u'    /*  update archive member */
  39. #define    VERBOSE_CMD    'v'    /*  controls amount of output */
  40. #define    EXTRACT_CMD    'x'    /*  extract archive member */
  41.  
  42. #define    USAGE_MESSAGE  "usage: ar1 [-](dptux)[v] archive [files]\n"
  43.  
  44. #define    HEADER_STRING  "#-h-"
  45. #define    TRAILER_STRING "#-t-"
  46. #define    NAMESIZE  20        /*  size of name allowed in header */
  47.  
  48. /*
  49.     The following depend on a properly defined notion of file type.
  50.     All strings should be the same length.
  51. */
  52.  
  53. #define    ASCII_STRING   "ascii "
  54. #define    LOCAL_STRING   "local "
  55. #define    BINARY_STRING  "binary"
  56. #define    ASCII          0
  57. #define    LOCAL          1
  58. #define    BINARY         2    
  59.  
  60.  
  61. /*
  62.     The file size (in chars) is computed for storage in the 
  63.     archive headers, although this information is not used.
  64. */
  65.  
  66. /*   GLOBAL VARIABLES    */
  67.  
  68. char *fname [MAXFILES];            /* list of file names        */
  69. int   fstat [MAXFILES];            /* status of each name in list    */
  70. int   fcount;                /* number of files on the list    */
  71.  
  72. char  chead [MAXLINE];            /* current header        */
  73.  
  74. int   errcnt;                /* error count            */
  75. int   verbose;                /* YES if verbose flag on    */
  76.  
  77.  
  78. main (argc,argv)
  79. int  argc;
  80. char **argv;
  81. {
  82.     _allocp = NULL;
  83.     dioinit(&argc, argv);
  84.     main1(argc, argv);
  85.     dioflush();
  86. }
  87.  
  88. main1(argc, argv)
  89. int argc;
  90. char **argv;
  91. {
  92.     char *archive, *command;
  93.     int i;
  94.  
  95.     /* initialize global error count */
  96.     errcnt = 0;
  97.  
  98.     /* make sure there is at least a command and an archive name */
  99.     if (argc < 3) {
  100.         fprintf(STD_ERR, "too few arguments\n");
  101.         error (USAGE_MESSAGE);
  102.     }
  103.  
  104.     /*
  105.         Put a list of file names into fnames [].
  106.         Check for duplicates.
  107.     */
  108.     get_fnames(argc, argv);
  109.  
  110.     /* point at the name of the archive */
  111.     archive = argv [2];
  112.     upper (archive);
  113.  
  114.     /* point at the options list */
  115.     command = argv [1];
  116.     lower (command);
  117.  
  118.     /* skip leading '-' if present */
  119.     if (command [0] == '-') {
  120.         i = 1;
  121.     }
  122.     else {
  123.         i = 0;
  124.     }
  125.  
  126.     if (command [i + 1] == VERBOSE_CMD) {
  127.         verbose = YES;
  128.     }
  129.     else if (command [i + 1] == EOS) {
  130.         verbose = NO;
  131.     }
  132.     else {
  133.         fprintf(STD_ERR, "option too long\n");
  134.         error (USAGE_MESSAGE);
  135.     }
  136.  
  137.     if (command [i] == UPDATE_CMD) {
  138.         update (archive);
  139.     }
  140.     else if (command [i] == TABLE_CMD) {
  141.         table (archive);
  142.     }
  143.     else if (command [i] == EXTRACT_CMD || command [i] == PRINT_CMD) {
  144.         extract (archive, command [i]);
  145.     }
  146.     else if (command [i] == DELETE_CMD) {
  147.         delete (archive);
  148.     }
  149.     else {
  150.         fprintf(STD_ERR, "unknown option\n");
  151.         error (USAGE_MESSAGE);
  152.     }
  153. }
  154.  
  155.  
  156. /* Add file 'name' to archive open on 'fd' */
  157.  
  158. add_file (name, fd)
  159. char *name;
  160. int fd;
  161. {
  162.     char head [MAXLINE], trail[MAXLINE];
  163.     int nfd;
  164.     char nfbuf [BUFSIZ];
  165.  
  166.     /* kludge for BDS C fopen */
  167.     nfd = nfbuf;
  168.  
  169.     if (fopen (name, nfbuf) == ERROR) {
  170.         fprintf(STD_ERR, "can't add %s\n", name);
  171.         errcnt++;
  172.         return;
  173.     }
  174.  
  175.     if (errcnt == 0) {
  176.         make_header (head, name);
  177.         if (verbose == YES) {
  178.             fprintf(STD_OUT, "%s\n", name);
  179.         }
  180.         put_line (head, fd);
  181.         copy_in (nfd, fd);
  182.         make_trailer (head, trail);
  183.         put_line (trail, fd);
  184.     }
  185.     fclose (nfd);
  186. }
  187.  
  188.  
  189. /*
  190.     Copy a file into an archive.
  191.     May have to be adjusted to allow for binary files.
  192. */
  193.  
  194. copy_in (fd, afd)
  195. int fd, afd;
  196. {
  197.     int c;
  198.  
  199.     while (1) {
  200.         /* allow abort with ^C from console */
  201.         chkkey();
  202.  
  203.         c = getc(fd);
  204.         if (c == ERROR || c == CPMEOF) {
  205.             break;
  206.         }
  207.         putc (c, afd);
  208.     }
  209. }
  210.  
  211.  
  212. /* Copy archive element from one archive to another */
  213.  
  214. copy_ele (oldafd, newafd)
  215. int oldafd, newafd;
  216. {
  217.     char line [MAXLINE];
  218.  
  219.     while (get_line (line, oldafd) != 0) {
  220.         put_line (line, newafd);
  221.         if (ele_end (line) == YES) {
  222.             return;
  223.         }
  224.     }
  225.     remark ("archive integrity in doubt - missing trailer.\n");
  226.     errcnt++;
  227. }
  228.  
  229.  
  230. /* Copy a file out of an archive */
  231.  
  232. copy_out (afd, fd)
  233. int afd, fd;
  234. {
  235.     char line [MAXLINE];
  236.     int  start;
  237.  
  238.     while (get_line (line, afd) != 0) {
  239.         if (ele_end (line) == YES) {
  240.             /*  we've copied the whole archive element */
  241.             return;
  242.         }
  243.         else {
  244.             put_line (line, fd);  /*  ordinary text */
  245.         }
  246.     }
  247.     remark ("archive integrity in doubt - missing trailer.\n");
  248.     errcnt++;
  249. }
  250.  
  251.  
  252. /* Delete files from the archive */
  253.  
  254. delete (aname)
  255. char *aname;
  256. {
  257.     int  tprefx;
  258.     char  tname [SYS_MAXFN];
  259.     int afd, tfd;
  260.     char afbuf [BUFSIZ], tfbuf[BUFSIZ];
  261.  
  262.     /* kludge for BDS C fopen, fcreat */
  263.     afd = afbuf;
  264.     tfd = tfbuf;
  265.  
  266.     tprefx = 0;
  267.     if (fcount <= 0) {
  268.         error ("delete by name only.\n");
  269.     }
  270.     if (fopen (aname, afbuf) == ERROR) {
  271.         cant (aname);
  272.     }
  273.  
  274.     mkunik (tprefx, tname); 
  275.     if (fcreat (tname, tfbuf) == ERROR) {
  276.         fprintf(STD_ERR, "can not create %s\n", tname);
  277.     }
  278.  
  279.     replace (afd, tfd, DELETE_CMD);
  280.     not_found ();
  281.  
  282.     fclose (afd);
  283.     putc (CPMEOF, tfd);
  284.     fflush (tfd);
  285.     fclose (tfd);
  286.     if (errcnt == 0) {
  287.         unlink (aname);
  288.         rename (tname,aname);
  289.     }
  290.     else {
  291.         remark ("fatal errors - archive not altered.\n");
  292.     }
  293.     unlink (tname);
  294. }
  295.  
  296.  
  297. /* Extract files from archive */
  298.  
  299. extract (archive, cmd)
  300. char *archive, cmd;
  301. {
  302.     char name [SYS_MAXFN], hdr[MAXLINE];
  303.     int afd, fd;
  304.     char    afbuf [BUFSIZ], fbuf[BUFSIZ];
  305.  
  306.     /* kludge for BDS C fopen, fcreat */
  307.     afd = afbuf;
  308.     fd  = fbuf;
  309.  
  310.     if (fopen (archive, afbuf) == ERROR) {
  311.         fprintf(STD_ERR, "can not open archive: %s\n", archive);
  312.         exit();
  313.     }    
  314.  
  315.     /* NOTE:  this code could be much improved by keeping track of the
  316.      *      number of files that have been extracted and exiting
  317.      *      when all have been found.
  318.      */
  319.  
  320.     while (get_header (afd, hdr, name) != EOF) {
  321.  
  322.         if (file_arg (name) == NO) {
  323.             skipf (afd);
  324.         }
  325.         else {
  326.             if (verbose == YES && cmd == PRINT_CMD) {
  327.                 fprintf(STD_OUT, "%s\n", name);
  328.             }
  329.             else if (verbose == YES) {
  330.                 fprintf(STD_OUT, "%s\n", name);
  331.             }
  332.  
  333.             if (cmd == PRINT_CMD) {
  334.                 copy_out (afd, STD_OUT);
  335.             }
  336.             else {
  337.                 if (fcreat (name, fbuf) != ERROR) {
  338.                     copy_out (afd, fd);
  339.                     putc (CPMEOF, fd);
  340.                     fflush (fd);
  341.                     fclose (fd);
  342.                 }
  343.                 else {
  344.                     fprintf(STD_ERR,
  345.                         "can not create %s\n", name);
  346.                     errcnt++;
  347.                     skipf (afd);
  348.                 }
  349.             }
  350.  
  351.         }
  352.     }
  353.     not_found();
  354. }
  355.  
  356.  
  357. /* See if name is present in argument list */
  358.  
  359. file_arg (name)
  360. char *name;
  361. {
  362.     int i;
  363.  
  364.     /* a null list matches ALL files */
  365.     if (fcount <= 0) {
  366.         return (YES);
  367.     }
  368.  
  369.     for (i = 0; i < fcount; i++) {
  370.         if (strcmp (name, fname [i]) == 0) {
  371.             fstat [i] = YES;
  372.             return (YES);
  373.         }
  374.     }
  375.     return (NO);
  376. }
  377.  
  378.  
  379. /* Determine size of file (in chars) */
  380.  
  381. unsigned
  382. fsize (name)
  383. char *name;
  384. {
  385.     int fd;
  386.     char fbuf [BUFSIZ];
  387.     unsigned count;
  388.     char line [MAXLINE];
  389.     int n;
  390.  
  391.     /* kludge for BDS C fopen */
  392.     fd = fbuf;
  393.  
  394.     if (fopen (name, fbuf) == ERROR) {
  395.         return (ERROR);
  396.     }
  397.  
  398.     count = 0;
  399.     while (n = get_line(line, fd)) {
  400.         count += n;
  401.     }
  402.  
  403.     fclose (fd);
  404.     return (count);
  405. }
  406.  
  407.  
  408. /*
  409.     Get file names into 'fname', check for duplicates.
  410.     File names are stored LOWER CASE.
  411. */
  412.  
  413. get_fnames(argc, argv)
  414. int argc;
  415. char **argv;
  416. {
  417.     int ap, fp, len, i;
  418.     char line [MAXLINE];
  419.  
  420.     for (fp = 0, ap = 3; ap < argc; ap++) {
  421.  
  422.         fname [fp] = argv[ap];
  423.         if (fname [fp][0] == '-' && fname [fp][1] == EOS) {
  424.             
  425.             while (fp < MAXFILES) {
  426.                 /* get list from standard input */
  427.  
  428.                 len = get_line (line, STD_IN);
  429.                 if (len <= 1) {
  430.                     break;
  431.                 }
  432.                 /* remove the NEWLINE */
  433.                 line [len-1] =EOS;
  434.  
  435.                 /* save it in dynamic storage */
  436.                 fname [fp] = strsav (line);
  437.                 lower (fname [f